#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <gtk/gtk.h>
#include <curl/curl.h>
#include <json-glib/json-glib.h>

//#define GNOME_DESKTOP_USE_UNSTABLE_API
//#include <libgnomeui/gnome-bg.h>
#include <gconf/gconf-client.h>
#include <stdio.h>

#include "callbacks.h"
#include "interface.h"
#include "support.h"

#define SIZE 4096
#define PROGRAM_NAME "beautifulmood"
#define PROGRAM_DIR ".beautifulmood"
#define FILE_COUNTS_NAME "pic-count"
#define MAX_PAGE 8
#define RESULTS_PER_PAGE 8
#define MAX_LENGTH_URL 1024

typedef enum {
        WALLPAPER_ALIGN_TILED = 0,
        WALLPAPER_ALIGN_CENTERED = 1,
        WALLPAPER_ALIGN_STRETCHED = 2,
        WALLPAPER_ALIGN_SCALED = 3,
        WALLPAPER_NONE = 4
} WallpaperAlign;

enum {
	THUMBNAIL = 0,
	ORIGINAL
};
enum {
	FIRST = 0,
	SECOND
};
typedef struct
{
	gchar *key;
	gchar *key_sum;
	gint page;
	gint start;
	gint sequence;
}SearchPara;
	
typedef struct 
{
	const gchar *width;
	const gchar *height;
	const gchar *imageId;
	const gchar *tbWidth;
	const gchar *tbHeight;
	const gchar *unescapedUrl;
	const gchar *url;
	const gchar *visibleUrl;
	const gchar *title;
	const gchar *titleNoFormatting;
	const gchar *originalContextUrl;
	const gchar *content;
	const gchar *contentNoFormatting;
	const gchar *tbUrl;
	const gchar *thumbnail;
	const gchar *local;
	const gchar *check_sum; /* check sum of the keywords */
	gint thumbstas;		/* thumbnail downloading status */
	gint page;		/* page num between 0-7 */
	gint position;		/* position between 0-7 */
} SearchResult;

enum DownloadStatus
{
	START = 0,
	DOWNLOADING,
	DOWNLOADED
};
static int pic_counts = 0;
static int image_position = 0;
const gchar *key_words = NULL;
static GtkWidget *main_window = NULL;
static GList * search_list;
static int backup_position = 0;
static int start = 0;
static int start_back = 0;
static int page = 0;
static int page_back = 0;
#if 0
GHashTable *search_result_items_set = NULL;
#endif
GHashTable *search_result_pages_set = NULL;

void set_background_with_url(SearchResult **result);
gchar *get_program_dir()
{
	//printf("get_program_dir\n");
	const gchar *home = g_getenv("HOME");
	gchar *program_dir = g_build_filename(home, PROGRAM_DIR, NULL);
	//printf("program_dir: %s\n", program_dir);
	if (!g_file_test(program_dir, G_FILE_TEST_IS_DIR))
		g_mkdir(program_dir, 0755);
	//printf("program_dir: %s\n", program_dir);
	//g_free(home);
	return program_dir;
}
void clear_results(GtkWidget *window)
{
	GtkWidget *image1 = lookup_widget (window, "image1");
	GtkWidget *image2 = lookup_widget (window, "image2");
	GtkWidget *image3 = lookup_widget (window, "image3");
	GtkWidget *image4 = lookup_widget (window, "image4");
	GtkWidget *image5 = lookup_widget (window, "image5");
	GtkWidget *image6 = lookup_widget (window, "image6");
	GtkWidget *image7 = lookup_widget (window, "image7");
	GtkWidget *image8 = lookup_widget (window, "image8");
	gtk_image_set_from_file(GTK_IMAGE(image1), NULL);
	gtk_image_set_from_file(GTK_IMAGE(image2), NULL);
	gtk_image_set_from_file(GTK_IMAGE(image3), NULL);
	gtk_image_set_from_file(GTK_IMAGE(image4), NULL);
	gtk_image_set_from_file(GTK_IMAGE(image5), NULL);
	gtk_image_set_from_file(GTK_IMAGE(image6), NULL);
	gtk_image_set_from_file(GTK_IMAGE(image7), NULL);
	gtk_image_set_from_file(GTK_IMAGE(image8), NULL);
}

gchar *get_key_words_dir(gchar *keywords)
{
	//printf("get_key_words_dir, keywords: %s\n", keywords);
	gchar *dir = get_program_dir();
	//printf("program dir: %s\n", dir);
	//gchar *words = g_build_filename(dir, keywords, NULL);
	//printf("words: %s\n", words);
	gchar *check_sum = g_compute_checksum_for_string(G_CHECKSUM_MD5,
							 keywords, 
							 -1);
	//printf("check_sum: %s\n", check_sum);
	gchar *pic_dir = g_build_filename(dir, check_sum, NULL);
	if (!g_file_test(pic_dir, G_FILE_TEST_IS_DIR))
		g_mkdir(pic_dir, 0755);
	//printf("pic dir: %s\n", pic_dir);
	g_free(dir);
	//g_free(words);
	g_free(check_sum);
	return pic_dir;
}
size_t my_write_func(void *ptr, size_t size, size_t nmemb, FILE *stream)
{
	return fwrite(ptr, size, nmemb, stream);
}

gint init_pic_counts_from_key_words(gchar *keywords)
{
	gint counts = 0;
	/* FIXME */
	/*
	  gchar *count_file = g_build_filename(dir, FILE_COUNTS_NAME, NULL);

	  gint count = 0;
	  if (g_file_test(count_file, G_FILE_IS_EXISTS))
	  {
	  count = 0;
	  }	
	*/
	return counts;
}

gchar *get_output_filename(const gchar *url, gint type)
{
	//printf("get_output_filename\n");
	gchar *dir = get_program_dir();// get_key_words_dir(key_words);
	//printf("dir: %s\n", dir);
	
	if (type == THUMBNAIL)
		dir = g_build_filename(dir, "thumbnail", NULL);
	else if (type == ORIGINAL)
		dir = g_build_filename(dir, "original", NULL);

	if (!g_file_test(dir, G_FILE_TEST_IS_DIR))
		g_mkdir(dir, 0755);
	
	gchar *check_sum = g_compute_checksum_for_string(G_CHECKSUM_MD5,
							 url, 
							 -1);

	//gchar *ext = url + strlen(url) - 3;
	//printf("ext: %s\n", ext);
	//gchar *file = g_strdup_printf("%d.%s", pic_counts++, ext);
	//gchar *output = g_build_filename(dir, file, NULL);
	gchar *output = g_build_filename(dir, check_sum, NULL);
	//printf("output: %s\n", output);
	g_free(dir);
	g_free(check_sum);

	return output;
}

/*
 * url: url to down
 * type: THUMBNAIL or ORIGINAL 
 */
const gchar *download_image_with_url(const gchar *url, gint type)
{
	gchar *output = get_output_filename(url, type);
	//printf("output: %s\n", output);
	//gchar *cmd = g_strdup_printf("axel %s -o %s", url, output);
	gchar *cmd = g_strdup_printf("wget %s -O %s > /dev/null 2>&1", url, output);
	printf("%s\n", cmd);
	system(cmd);
	g_free(cmd);

	if (g_file_test(output, G_FILE_TEST_EXISTS))
		return output;
	else
		return NULL;
}

gint get_position(GtkWidget *label)
{
  printf("on_image_button_1_release_event\n");
  GtkWidget *label1 = lookup_widget (main_window, "label_result_1");
  GtkWidget *label2 = lookup_widget (main_window, "label_result_2");
  GtkWidget *label3 = lookup_widget (main_window, "label_result_3");
  GtkWidget *label4 = lookup_widget (main_window, "label_result_4");
  GtkWidget *label5 = lookup_widget (main_window, "label_result_5");
  GtkWidget *label6 = lookup_widget (main_window, "label_result_6");
  GtkWidget *label7 = lookup_widget (main_window, "label_result_7");
  GtkWidget *label8 = lookup_widget (main_window, "label_result_8");
  GtkWidget *label9 = lookup_widget (main_window, "label_result_9");
  GtkWidget *label10 = lookup_widget (main_window, "label_result_10");
  GtkWidget *label11 = lookup_widget (main_window, "label_result_11");
  GtkWidget *label12 = lookup_widget (main_window, "label_result_12");
  GtkWidget *label13 = lookup_widget (main_window, "label_result_13");
  GtkWidget *label14 = lookup_widget (main_window, "label_result_14");
  GtkWidget *label15 = lookup_widget (main_window, "label_result_15");
  GtkWidget *label16 = lookup_widget (main_window, "label_result_16");

  int position = 0;
  if (label == label1)
    position = 0;
  else if (label == label2)
    position = 1;
  else if (label == label3)
    position = 2;
  else if (label == label4)
    position = 3;
  else if (label == label5)
    position = 4;
  else if (label == label6)
    position = 5;
  else if (label == label7)
    position = 6;
  else if (label == label8)
    position = 7;
  else if (label == label9)
    position = 8;
  else if (label == label10)
    position = 9;
  else if (label == label11)
    position = 10;
  else if (label == label12)
    position = 11;
  else if (label == label13)
    position = 12;
  else if (label == label14)
    position = 13;
  else if (label == label15)
    position = 14;
  else if (label == label16)
    position = 15;

  return position;
}

static gboolean
activate_link (GtkWidget   *label,
               const gchar *uri,
               gpointer     data)
{
  printf("activate_link\n");
  printf("uri: %s\n", uri);

  backup_position = get_position(label);

/*
  gchar *check_sum = g_compute_checksum_for_string(G_CHECKSUM_MD5,
						   key_words, 
						   -1);
  gchar *key = g_strdup_printf("%s-%d-%d", check_sum, page, position);
  printf("key: %s\n", key);
  printf("click position: %d\n", position);
  SearchResult * result = g_hash_table_lookup(search_result_items_set, key);
*/
  SearchResult **result = (SearchResult **)data;

  GError *error;
  GThread *t = g_thread_create((GThreadFunc)set_background_with_url,
			       result,
			       TRUE,
			       &error);
  if (!t)
    printf("error: %s\n", error->message);

}

gboolean set_image_from_file(SearchResult **result)
{
	printf("set_image_from_file\n");
	printf("positon 3: %d\n", (*result)->position);
	GtkWidget *image = NULL;
	GtkWidget *label = NULL;

	switch((*result)->position)
	{
	case 0:
		image = lookup_widget (main_window, "image1");	
		label = lookup_widget (main_window, "label_result_1");	
		break;
	case 1:
		image = lookup_widget (main_window, "image2");
		label = lookup_widget (main_window, "label_result_2");	
		break;
	case 2:
		image = lookup_widget (main_window, "image3");
		label = lookup_widget (main_window, "label_result_3");	
		break;
	case 3:
		image = lookup_widget (main_window, "image4");
		label = lookup_widget (main_window, "label_result_4");
		break;
	case 4:
		image = lookup_widget (main_window, "image5");
		label = lookup_widget (main_window, "label_result_5");
		break;
	case 5:
		image = lookup_widget (main_window, "image6");
		label = lookup_widget (main_window, "label_result_6");
		break;
	case 6:
		image = lookup_widget (main_window, "image7");
		label = lookup_widget (main_window, "label_result_7");
		break;
	case 7:
		image = lookup_widget (main_window, "image8");
		label = lookup_widget (main_window, "label_result_8");
		break;
	case 8:
		image = lookup_widget (main_window, "image9");	
		label = lookup_widget (main_window, "label_result_9");	
		break;
	case 9:
		image = lookup_widget (main_window, "image10");	
		label = lookup_widget (main_window, "label_result_10");	
		break;
	case 10:
		image = lookup_widget (main_window, "image11");	
		label = lookup_widget (main_window, "label_result_11");	
		break;
	case 11:
		image = lookup_widget (main_window, "image12");
		label = lookup_widget (main_window, "label_result_12");	
		break;
	case 12:
		image = lookup_widget (main_window, "image13");
		label = lookup_widget (main_window, "label_result_13");	
		break;
	case 13:
		image = lookup_widget (main_window, "image14");
		label = lookup_widget (main_window, "label_result_14");
		break;
	case 14:
		image = lookup_widget (main_window, "image15");
		label = lookup_widget (main_window, "label_result_15");
		break;
	case 15:
		image = lookup_widget (main_window, "image16");
		label = lookup_widget (main_window, "label_result_16");
		break;
	}

	if (image)
	{
		gchar *text = g_strdup_printf("<a href=\"http://www.163.com\">%s</a>", (*result)->title);
		//gchar *text = g_strdup_printf("<a>%s</a>", result->titleNoFormatting);
		printf("text: %s\n", text);
		//label = gtk_label_new (text);
		gtk_label_set_text(label, text);
		printf("gtk_label_set_text\n");
		gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
		printf("gtk_label_set_use_markup \n");
		g_signal_connect (label, "activate-link", G_CALLBACK (activate_link), result);
		printf("g_signal_connect \n");
		gtk_widget_show(label);
		printf("gtk_widget_show\n");
	}
	if (label)
	{
		gtk_image_set_from_file(GTK_IMAGE(image), (*result)->thumbnail);
		printf("gtk_image_set_from_file\n");
		gtk_widget_show(image);
	}
	image_position++;

	return FALSE;
}

gboolean set_as_wallpaper( const gchar *image_path, WallpaperAlign align )
{
	printf("enter set_as_wallpaper\n");
	GConfClient *client;
	char *options = "none";
	client = gconf_client_get_default();
	printf("get client conf\n");
	// TODO: check that image_path is a file
	if ( image_path == NULL ) 
		options = "none";
	else 
	{
		gconf_client_set_string( client,
					 "/desktop/gnome/background/picture_filename",
					 image_path,
					 NULL );
		printf("gconf_client_set_string\n");
		switch ( align ) 
		{
		case WALLPAPER_ALIGN_TILED: options = "wallpaper"; break;
		case WALLPAPER_ALIGN_CENTERED: options = "centered"; break;
		case WALLPAPER_ALIGN_STRETCHED: options = "stretched"; break;
		case WALLPAPER_ALIGN_SCALED: options = "scaled"; break;
		case WALLPAPER_NONE: options = "none"; break;
		}
	}
	printf("option: %s\n", options);
	gboolean result = gconf_client_set_string( client,
						   "/desktop/gnome/background/picture_options",
						   options,
						   NULL);
	g_object_unref( G_OBJECT(client) );
	return result;
}

void set_image_with_url(SearchResult **result)
{
	printf("set_image_with_url\n");
	(*result)->thumbstas = DOWNLOADING;
	(*result)->thumbnail = download_image_with_url((*result)->tbUrl, THUMBNAIL);
	(*result)->thumbstas = DOWNLOADED;
	printf("positon 2: %d\n", (*result)->position);

	//printf("set %s as thumbnail\n", (*result)->thumbnail);	
	g_idle_add((GSourceFunc)set_image_from_file, result);
}

void set_background_with_url(SearchResult **result)
{
	if (!g_file_test((*result)->local, G_FILE_TEST_EXISTS))
		(*result)->local = download_image_with_url((*result)->url, ORIGINAL);

	/* FIXME: set as background */
	//GnomeBG *bg = gnome_bg_new();
	//gnome_bg_set_filename(bg, (*result)->local);

	printf("backup_position: %d; (*result)->position: %d\n", backup_position, (*result)->position);
	if (backup_position == (*result)->position)
	{
		printf("will set %s as background\n", (*result)->local);
		set_as_wallpaper((*result)->local, WALLPAPER_ALIGN_STRETCHED);
	}
	else
	{
		printf("set backup position is not match this one, do not set background\n");	
	}
}
SearchResult *search[RESULTS_PER_PAGE*2];
/* GList * */
void get_image_result_list(gchar *file, SearchPara *sp)
{
	/* GList *list = NULL; */
	GError *error = NULL;
	const gchar *str;
	const gchar *value;
	gint i = 0;
	
	gchar *check_sum = g_compute_checksum_for_string(G_CHECKSUM_MD5, sp->key, -1);

	JsonParser *parser = json_parser_new();
	if (!json_parser_load_from_file(parser, file, &error))
		printf("json_parser_load_from_file failed, %s\n", error->message);
	JsonNode *root = json_parser_get_root(parser);
	JsonObject *root_obj = json_node_get_object (root);
	//GList *nodes = json_object_get_members(root_obj);
	JsonObject *response_data = json_object_get_object_member(root_obj, "responseData");
	g_print("get response data\n");
	JsonNode *results_node = json_object_get_member(response_data, "results");
	JsonArray *results_array = json_node_get_array(results_node);
	GList *search_result = json_array_get_elements(results_array);
	GList *list_results = search_result;
	int j;
	while (list_results)
	{
		JsonObject *search_obj = json_node_get_object((JsonNode *)list_results->data);
		j = i + (sp->sequence) * RESULTS_PER_PAGE;
		printf("process i: %d; j: %d\n", i, j);
		search[j] = g_malloc(sizeof(SearchResult));
		search[j]->width = json_object_get_string_member(search_obj, "width");
		search[j]->height = json_object_get_string_member(search_obj, "height");
		search[j]->imageId = json_object_get_string_member(search_obj, "imageId");
		search[j]->tbWidth = json_object_get_string_member(search_obj, "tbWidth");
		search[j]->tbHeight = json_object_get_string_member(search_obj, "tbHeight");
		search[j]->unescapedUrl = json_object_get_string_member(search_obj, "unescapedUrl");
		search[j]->url = json_object_get_string_member(search_obj, "url");
		search[j]->visibleUrl = json_object_get_string_member(search_obj, "visibleUrl");
		search[j]->title = json_object_get_string_member(search_obj, "title");
		search[j]->titleNoFormatting = json_object_get_string_member(search_obj, "titleNoFormatting");
		search[j]->originalContextUrl = json_object_get_string_member(search_obj, "originalContextUrl");
		search[j]->content = json_object_get_string_member(search_obj, "content");
		search[j]->contentNoFormatting = json_object_get_string_member(search_obj, "contentNoFormatting");
		search[j]->tbUrl = json_object_get_string_member(search_obj, "tbUrl");
		search[j]->position = j;
		printf("positon 1: %d\n", search[j]->position);

		/* start a thread to down this picture */
		g_thread_create((GThreadFunc)set_image_with_url, 
				&search[j],
				TRUE,
				&error);	

		i++;
		/* list = g_list_append(list, search); */
		list_results = list_results->next;
	}
	/* return list; */
}

void urlenc(const char* str, char* buf)
{
	const char special[] = "!\"#$%& '()*+,/:; <=> ?@[\\]^`{|}~% "; /* special characters */
	char tmp[10]; /* temp buffer */
	//buf[0] = '';
	//buf[0] = '\0 ';
	int i;
	for(i=0; i <strlen(str); i++)
	{
		char c = str[i];
		if(strchr(special, c)) /* special character */
		{
			sprintf(tmp, "%%%02X", (unsigned char)c);
			strcat(buf, tmp);
		}
		else if(c == ' ') /* blank */
			strcat(buf, "+ ");
		else
		{
			if(c < 0) /* none ASCII character */
			{
				sprintf(tmp, "%%%02X%%%02X", (unsigned char)str[i], (unsigned char)str[i+1]);
				strcat(buf, tmp);
				++i;
			}
			else /* ASCII character */
			{
				sprintf(tmp, "%c", c);
				strcat(buf, tmp);
			}
		}
	}
}

gchar *get_search_flag(gchar *key, gint start)
{
	gchar *flag = g_strdup_printf("%s%d", key, start);
	gchar *check_sum = g_compute_checksum_for_string(G_CHECKSUM_MD5,
							 flag, 
							 -1);


	//g_free(flag);
	return check_sum;
}
GHashTable *searched_hash = NULL;
static SearchPara s;
static SearchPara b;

#define INIT_STAT "init"
#define SEARCHED "searched"
void do_search(SearchPara *sp)
{
	printf("do_search\n");
	printf("start: %d, page: %d, key: %s; key_sum: %s\n", sp->start, sp->page, sp->key, sp->key_sum);
	printf("\n");
	/* init searched table */
	gchar *pos = NULL;
	int m = 0;
	if (!searched_hash)
	{
		printf("init searched_hash\n");
		searched_hash = g_hash_table_new(g_str_hash, g_str_equal);

#if 0
		while(m < MAX_PAGE)
		{
			printf("key: %s", sp->key_sum);
			pos = g_strdup_printf("%s%d", sp->key_sum, m);
			printf("insert hash table: %s---------->%s\n", pos, INIT_STAT);
			g_hash_table_insert(searched_hash, pos, INIT_STAT);
	
			m++;
		}
#endif
	}
	printf("image_position = 0\n");
	//main_window = window1;
	image_position = 0;	

	//int i = 0;
	SearchResult *search;

	gchar *f = g_strdup_printf("%s%d", sp->key_sum, sp->page);//get_search_flag(sp->key, sp->start);
	printf("name(f): %s\n", f);
	gchar *v = g_hash_table_lookup(searched_hash, f);
	printf("flag(v): %s\n", v);
	printf("start: %d, page: %d, key: %s; key_sum: %s\n", sp->start, sp->page, sp->key, sp->key_sum);

	/* already searched or not */
	if (!v)
	{
		printf("not searched, do it\n");
		CURL *curl;
		CURLcode res;
		printf("start: %d, page: %d, key: %s; key_sum: %s\n", sp->start, sp->page, sp->key, sp->key_sum);
		char encode_key_words[MAX_LENGTH_URL];
		urlenc(sp->key, encode_key_words);
		printf("encodeed keywords: %s\n", encode_key_words);
		gchar *url = g_strdup_printf("http://ajax.googleapis.com/ajax/services/search/images?v=1.0&rsz=large&start=%d&imgsz=xxlarge&as_filetype=jpg&q=%s", sp->start, encode_key_words);
		printf("exec url:\n%s\n", url);

		const gchar *home = g_getenv("HOME");
		gchar *outfile = g_build_filename(home, ".search", NULL);
		FILE *out = fopen(outfile, "w");

		curl = curl_easy_init(); 
		if(curl!=NULL)
		{
			curl_easy_setopt(curl, CURLOPT_URL, url);
			curl_easy_setopt(curl, CURLOPT_WRITEDATA, out);
			curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_write_func);
			res = curl_easy_perform(curl);
			curl_easy_cleanup(curl);
		}
		fclose(out);
		printf("fclose(out)\n");

		get_image_result_list(outfile, sp);
	}
	else
	{

	}
	printf("searched\n");
	g_free(f);
	printf("free f\n");
	//g_free(outfile);
	printf("############################################################\n");
}


void
on_q_button_clicked                    (GtkWidget *window1,
					gpointer         user_data)
{
	GtkWidget *window = window1;
	clear_results(window);

	GError *error;
	GtkWidget *q = lookup_widget (window1, "q_entry");

	s.page = 0;
	s.sequence = FIRST;
	s.start = s.page * RESULTS_PER_PAGE;
	s.key = gtk_entry_get_text(GTK_ENTRY(q));
	s.key_sum = g_compute_checksum_for_string(G_CHECKSUM_MD5,
						  s.key, 
						  -1);

	GThread *t = g_thread_create((GThreadFunc)do_search, 
				     &s, 
				     TRUE,
				     &error);	

	/* search the half below */
	b.page = 1;
	b.sequence = SECOND;
	b.start = b.page * RESULTS_PER_PAGE;
	b.key = gtk_entry_get_text(GTK_ENTRY(q));
	b.key_sum = g_compute_checksum_for_string(G_CHECKSUM_MD5,
						  b.key, 
						  -1);

	page_back = b.page;
	key_words = b.key;
	start_back = b.start;
	printf("key words: %s\n", key_words);

	t = g_thread_create((GThreadFunc)do_search, 
				     &b, 
				     TRUE,
				     &error);	
}

gboolean
on_image_key_release_event             (GtkWidget       *widget,
                                        GdkEventKey     *event,
                                        gpointer         user_data)
{
	printf("on_image_key_release_event\n");
	return FALSE;
}


gboolean
on_image1_button_release_event         (GtkWidget       *widget,
                                        GdkEventButton  *event,
                                        gpointer         user_data)
{
	printf("on_image1_button_release_event\n");
	return FALSE;
}


void
on_image_button_1_released             (GtkButton       *button,
                                        gpointer         user_data)
{
	printf("on_image_button_1_release_event\n");
	GtkButton *button1 = (GtkButton*)lookup_widget (main_window, "imagebutton1");
	GtkButton *button2 = (GtkButton*)lookup_widget (main_window, "imagebutton2");
	GtkButton *button3 = (GtkButton*)lookup_widget (main_window, "imagebutton3");
	GtkButton *button4 = (GtkButton*)lookup_widget (main_window, "imagebutton4");
	GtkButton *button5 = (GtkButton*)lookup_widget (main_window, "imagebutton5");
	GtkButton *button6 = (GtkButton*)lookup_widget (main_window, "imagebutton6");
	GtkButton *button7 = (GtkButton*)lookup_widget (main_window, "imagebutton7");
	GtkButton *button8 = (GtkButton*)lookup_widget (main_window, "imagebutton8");

	int position = 0;
	if (button == button1)
		position = 0;
	else if (button == button2)
		position = 1;
	else if (button == button3)
		position = 2;
	else if (button == button4)
		position = 3;
	else if (button == button5)
		position = 4;
	else if (button == button6)
		position = 5;
	else if (button == button7)
		position = 6;
	else if (button == button8)
		position = 7;

	printf("click position: %d\n", position);
	backup_position = position;

	/* get the SearchResult */
	GList *list = search_list;
	//SearchResult *result;
	while (list)
	{
		//result = (SearchResult *)list->data;
		if (((SearchResult *)list->data)->position == position)
			break;
		list = list->next;
	}

	/* FIXME: start a thread to down this picture */
	GError *error;
	GThread *t = g_thread_create((GThreadFunc)set_background_with_url,
				     &list->data,
				     TRUE,
				     &error);
	if (!t)
		printf("error: %s\n", error->message);

}


void
on_button_page_up_clicked              (GtkButton       *button,
                                        gpointer         user_data)
{
	if (page_back <= 0)
	{
		s.page = 0;
		page_back = s.page;
		g_print("start < 0, retutn\n");
		return ;
	}

	/* clear the images */
	GtkWidget *window = GTK_WIDGET(button);
	clear_results(window);

	s.page = page_back - 1;
	s.sequence = FIRST;
	s.start = s.page * RESULTS_PER_PAGE;
	s.key = key_words;
	s.key_sum = g_compute_checksum_for_string(G_CHECKSUM_MD5,
						  s.key, 
						  -1);

	GError *error;
	GThread *t = g_thread_create((GThreadFunc)do_search, 
				     &s,
				     TRUE,
				     &error);
	/* search the half below */
	b.page = 1;
	b.sequence = SECOND;
	b.start = b.page * RESULTS_PER_PAGE;
	b.key = key_words;
	b.key_sum = g_compute_checksum_for_string(G_CHECKSUM_MD5,
						  b.key, 
						  -1);

	page_back = b.page;
	key_words = b.key;
	start_back = b.start;
	printf("key words: %s\n", key_words);

	t = g_thread_create((GThreadFunc)do_search, 
				     &b, 
				     TRUE,
				     &error);	
}

void
on_button_page_down_clicked            (GtkButton       *button,
                                        gpointer         user_data)
{
	if (page_back >= (MAX_PAGE-1))
	{
		s.page = MAX_PAGE - 1;
		page_back = s.page;
		g_print("start > 64, retutn\n");
		return ;
	}

	/* clear the images */
	GtkWidget *window = GTK_WIDGET(button);
	clear_results(window);

	s.page = page_back + 1;
	s.sequence = FIRST;
	s.start = s.page * RESULTS_PER_PAGE;
	s.key = key_words;
	s.key_sum = g_compute_checksum_for_string(G_CHECKSUM_MD5,
						  s.key, 
						  -1);

	GError *error;
	GThread *t = g_thread_create((GThreadFunc)do_search, 
				     &s,
				     TRUE,
				     &error);	
	/* search the half below */
	b.page = 1;
	b.sequence = SECOND;
	b.start = b.page * RESULTS_PER_PAGE;
	b.key = key_words;
	b.key_sum = g_compute_checksum_for_string(G_CHECKSUM_MD5,
						  b.key, 
						  -1);

	page_back = b.page;
	key_words = b.key;
	start_back = b.start;
	printf("key words: %s\n", key_words);

	t = g_thread_create((GThreadFunc)do_search, 
				     &b, 
				     TRUE,
				     &error);	
}
static gboolean
words_activate (GtkWidget   *label,
               const gchar *uri,
               gpointer     data)
{
	printf("words_activate\n");
	clear_results(main_window);

	GError *error;

	s.page = 0;
	s.sequence = FIRST;
	s.start = s.page * RESULTS_PER_PAGE;
	s.key = g_strdup(uri);
	s.key_sum = g_compute_checksum_for_string(G_CHECKSUM_MD5,
						  s.key, 
						  -1);

	printf("key words: %s; start: %d; key sum: %s\n", key_words, s.start, s.key_sum);

	GThread *t = g_thread_create((GThreadFunc)do_search, 
				     &s, 
				     TRUE,
				     &error);	

	/* search the half below */
	b.page = 1;
	b.sequence = SECOND;
	b.start = b.page * RESULTS_PER_PAGE;
	b.key = g_strdup(uri);
	b.key_sum = g_compute_checksum_for_string(G_CHECKSUM_MD5,
						  b.key, 
						  -1);

	page_back = b.page;
	key_words = b.key;
	start_back = b.start;
	printf("key words: %s\n", key_words);

	t = g_thread_create((GThreadFunc)do_search, 
				     &b, 
				     TRUE,
				     &error);	

}

gchar *get_content_from_file(gchar *file)
{
	FILE *fp = fopen(file, "r");
	if (!fp)
	{
		perror("fopen failed: ");
		return NULL;
	}

	char ch;
	gchar *text = NULL;
	while ((ch = fgetc(fp)) != EOF)
	{
		if (text)
			text = g_strdup_printf("%s%c", text, ch);
		else
			text = g_strdup_printf("%c", ch);
	}

	fclose(fp);

	return text;
}

void init_words_from_file(GtkWidget *label1, gchar *file)
{
	GtkWidget *label = lookup_widget (main_window, "label_words");
	printf("init_words_from_file\n");
	gchar *text = get_content_from_file(file);
	printf("%s\n", text);
	gtk_label_set_text(GTK_LABEL(label), text);
	gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
	g_signal_connect (label, "activate-link", G_CALLBACK (words_activate), NULL);
	gtk_widget_show(label); 
	//g_free(text);
}

void init_words(GtkWidget *window)
{
	main_window = window;
	printf("init_words\n");
	//GtkWidget *label = lookup_widget (window, "label_words");
	gchar *file = g_build_filename(get_program_dir(), "words", NULL);
	printf("file: %s\n", file);
	init_words_from_file(NULL, file);

#if 0
	if(!search_result_items_set)
		search_result_items_set = g_hash_table_new(g_str_hash, g_str_equal);
#endif
}
